📄 HƯỚNG DẪN QUẢN TRỊ HIỆU NĂNG QUERY QUA CHỈ SỐ "ĐỘ LỆCH CHUẨN" (STDDEV)
Trong quản trị hiệu năng PostgreSQL, chỉ số Mean (Trung bình) chỉ cho thấy bề nổi. Để đánh giá hệ thống có thực sự ổn định hay không, chúng ta phải soi kỹ cột stddev_exec_time (Độ lệch chuẩn - viết tắt: StdDev).
1. 🔍 Ý NGHĨA CỦA CHỈ SỐ STDDEV (ĐỘ LỆCH CHUẨN)
Độ lệch chuẩn cho biết mức độ biến động thời gian thực thi giữa các lần gọi query.
| Chỉ số StdDev | Trạng thái | Đọc vị hiệu năng |
|---|---|---|
| Thấp (< 10% Mean) | ✅ ỔN ĐỊNH | Query luôn chạy nhanh bất kể điều kiện tải. Index hoạt động hoàn hảo. |
| Cao (> 50% - 200% Mean) | 🚨 CẢNH BÁO ĐỎ | Hiện tượng "lúc nhanh lúc chậm" (Jitter). Query có dấu hiệu bị nghẽn cục bộ. |
Ví dụ: Một query có Mean là 3ms nhưng StdDev lên tới 35ms. Nghĩa là phần lớn chạy rất nhanh, nhưng thỉnh thoảng có những cú vọt (spike) lên tới 70-100ms gây lag App cục bộ cho giáo viên.
2. 🕵️ TRUY TÌM NGUYÊN NHÂN KHI STDDEV TĂNG CAO
Khi phát hiện query có độ lệch chuẩn lớn, team cần kiểm tra ngay 4 "nghi phạm" sau:
- Tranh chấp tài nguyên (Wait Events): Query bị nghẽn do phải đợi các tiến trình khác Write vào cùng bảng hoặc đợi cấp phát bộ nhớ (Lock).
- Thiếu Index đặc thù: Một số bộ Filter đặc biệt khiến Postgres phải quét toàn bộ bảng (Seq Scan) thay vì dùng Index.
- Giới hạn OS/Container (Shared Memory): Điển hình là giới hạn
ulimit -l. Khi OS bóp RAM, Postgres không thể nới rộng vùng nhớ (DSM resize) khiến query bị khựng hoặc lỗi Fatal. - Cấu trúc JSON quá lớn (Hasura/PostGraphile): Dữ liệu trả về qua
json_aggquá nặng ở một số bản ghi cụ thể (ví dụ trường có quá nhiều dữ liệu con) khiến Postgres mất nhiều thời gian đóng gói JSON trong RAM.
🛠️ CÂU LỆNH TRUY VẾT HUNG THỦ (SQL)
Team sử dụng script sau để liệt kê Top 5 Query đang gây tải và có biến động lớn nhất:
SELECT
query AS "Full_Query_Content", -- Hiển thị toàn bộ câu lệnh SQL
calls AS "Calls",
round(total_exec_time::numeric / 1000, 2) AS "Total_CPU_Sec",
round(mean_exec_time::numeric, 2) AS "Mean_ms",
round(stddev_exec_time::numeric, 2) AS "StdDev_ms",
round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 2) AS "Load_Percent"
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 5;